//////////////////////////////////////////////////////////////////////////////////
//
//	dod tackle
//		- Version 1.2b
//		- 11.18.2006
//		- diamond-optic
//
//////////////////////////////////////////////////////////////////////////////////
//
// Information:
//
// - Sprint into enemy players (or teammates with ff on) to do the following:
//	* knock the weapon out of their hands (if they are using primary weapon)
//	* knock them down on the ground (if not already prone)
//	* quick little screenfade
//	* push the player when you hit them (faster your going harder you push them)
//	* do damage to the player
// - Theres also a quicker fade for the attacker so you know when you hit someone
// - Various CVAR settings to control various aspects
// - Can Set it so admins can 'hit' teammates even with ff off
// - Logs various details for psychostats to pick up (thanks TatsuSaisei)
// - Has NO effect on bots (because commands like drop & prone cant be called on them)
//
//////////////////////////////////////////////////////////////////////////////////
//
// CVARs:
//
// 	dod_tackle "1"			//turn ON(1)/OFF(0) plugin
//
//	dod_tackle_speed "200"		//minimum speed (while sprinting)
//
//	dod_tackle_use "0"		//turn ON(1)/OFF(0) needing to press +use key
//					//while sprinting. Setting to "1" while having
//					//friendly fire on is useful so you dont hit
//					//teammates all the time...
//
//	dod_tackle_admins "0"		//turn ON(1)/OFF(0) admins being able to hit
//					//teammates even when ff is off (def. admin: immunity)
//
//	dod_tackle_ff "2"		//determines how plugin behaves in FF situations...
//						//"0" = NO friendly fire no matter what
//						//"1" = ALWAYS friendly fire
//						//"2" = Obeys mp_friendlyfire setting
//
//
//	dod_tackle_drop "1"		//turn ON(1)/OFF(0) dropping weapon (if using primary)
//	dod_tackle_dropchance "2"	//chance of dropping weapon (1 in # chance)
//
//	dod_tackle_prone "1"		//turn ON(1)/OFF(0) forcing prone
//	dod_tackle_pronechance "2"	//chance of forcing prone (1 in # chance)
//
//	dod_tackle_fade "1"		//turn ON(1)/OFF(0) screenfade
//	dod_tackle_fadechance "1"	//chance of screenfade (1 in # chance)
//	dod_tackle_fade_attacker "1"	//turn ON(1)/OFF(0) screenfade for the attacker
//
//	dod_tackle_push "1"		//turn ON(1)/OFF(0) pushing te victim
//	dod_tackle_pushchance "2"	//chance of pushing the victim (1 in # chance)
//
//	dod_tackle_dmg "1"		//turn ON(1)/OFF(0) doing damage
//	dod_tackle_dmgchance "4"	//chance of doing damage (1 in # chance)
//	dod_tackle_dmgamt "25"		//amount of damage for each hit
//
//////////////////////////////////////////////////////////////////////////////////
//
// EXTRA:
//
//	- The TACKLE_ADMIN define controls the admin level used (default: immunity)
//
//////////////////////////////////////////////////////////////////////////////////
//
// Changelog:
//
// - 11.07.2006 Version 1.0
//	Initial Release
//
// - 11.13.2006 Version 1.1
//	Added new hit & damage sounds
//
// - 11.18.2006 Version 1.2
//	Fixed typo in the CVAR list comment (missing last 'c' in dod_tackle_fade_attacker)
//	Added CVAR to control how the plugin acts with friendly fire
//	Fixed being able to still hit bots
//
// - 11.18.2006 Version 1.2b
//	Fixed getting player team before checking if its really a player (im so dumb)
//
//////////////////////////////////////////////////////////////////////////////////

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <dodfun>
#include <dodx>

#define TACKLE_ADMIN	ADMIN_IMMUNITY	//Admin Level

new gMsgScreenFade
new p_tackle, p_speed, p_use, p_admins, p_fade2, p_ff
new p_drop, p_dropchance, p_prone, p_pronechance, p_fade, p_fadechance, p_dmg, p_dmgchance, p_dmgamt, p_push, p_pushchance
new Float:hitTime[33]
new bool:log_block_state = false

new tackle_sounds[15][] =
{
	"player/damage1.wav",
	"player/damage2.wav",
	"player/damage3.wav",
	"player/damage4.wav",
	"player/damage5.wav",
	"player/damage6.wav",
	"player/damage7.wav",
	"player/damage8.wav",
	"player/damage9.wav",
	"player/damage10.wav",
	"player/damage11.wav",
	"common/bodydrop1.wav",
	"common/bodydrop2.wav",
	"common/bodydrop3.wav",
	"common/bodydrop4.wav"
}

public plugin_init()
{
	register_plugin("DoD Tackle","1.2b","AMXX DoD Team")
	register_cvar("dod_tackle_stats", "1.2b", FCVAR_SERVER|FCVAR_SPONLY)
	
	register_forward(FM_Touch, "touch")
	register_forward(FM_AlertMessage,"block_log")
	gMsgScreenFade = get_user_msgid("ScreenFade")
	
	p_tackle = register_cvar("dod_tackle","1")
	p_speed = register_cvar("dod_tackle_speed", "200")
	p_use = register_cvar("dod_tackle_use", "0")
	p_admins = register_cvar("dod_tackle_admins" , "0")
	p_ff = register_cvar("dod_tackle_ff" , "2")
		
	p_drop = register_cvar("dod_tackle_drop","1")
	p_dropchance = register_cvar("dod_tackle_dropchance","2")
	p_prone = register_cvar("dod_tackle_prone","1")
	p_pronechance = register_cvar("dod_tackle_pronechance","2")
	p_fade = register_cvar("dod_tackle_fade","1")
	p_fadechance = register_cvar("dod_tackle_fadechance","1")
	p_fade2 = register_cvar("dod_tackle_fade_attacker","1")
	p_push = register_cvar("dod_tackle_push","1")
	p_pushchance = register_cvar("dod_tackle_pushchance","2")
	p_dmg = register_cvar("dod_tackle_dmg","1")
	p_dmgchance = register_cvar("dod_tackle_dmgchance","4")
	p_dmgamt = register_cvar("dod_tackle_dmgamt","25")
}

public plugin_precache()
{
	for(new i = 0; i < 15; ++i)
		precache_sound(tackle_sounds[i])
}

public touch(id,ent)
{
	if(get_pcvar_num(p_tackle) != 1 || !pev_valid(id) || !pev_valid(ent) || id>32 || ent>32|| id<1 || ent<1)
		return PLUGIN_HANDLED

	new classname[32], classname2[32]
	pev(id,pev_classname, classname, 31)
	pev(ent,pev_classname, classname2, 31)
		
	if(equali(classname,"player") && equali(classname2,"player"))
		{	
		if(!is_user_bot(id) && !is_user_bot(ent) && is_user_alive(id) && is_user_alive(ent) && is_user_connected(id) && is_user_connected(ent) && dod_get_pronestate(ent) == 0 && ((get_pcvar_num(p_use) == 1 && pev(id, pev_button) & IN_USE && pev(id, pev_button) & IN_RUN) || (get_pcvar_num(p_use) != 1 && pev(id, pev_button) & IN_RUN)))
			{
			new team = get_user_team(id)	
			new other_team = get_user_team(ent)
				
			if(team != other_team || (team == other_team && ((get_cvar_num("mp_friendlyfire") == 1 && get_pcvar_num(p_ff) == 2) || get_pcvar_num(p_ff) == 1)) || (access(id,TACKLE_ADMIN) && get_pcvar_num(p_admins)))
				{
				new Float:Vel[3], speed
				pev(id, pev_velocity, Vel)
				speed = floatround(vector_length(Vel))
	
				if(speed >= get_pcvar_num(p_speed) && get_gametime() > hitTime[id])
					{
					new steam[32], teamname[32], name[32]
					get_user_authid(id, steam, 31)
					dod_get_pl_teamname(id, teamname, 31)
					get_user_name(id, name, 31)
															
					log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"tackle^") (shots ^"1^") (hits ^"1^") (kills ^"0^") (headshots ^"0^") (tks ^"0^") (damage ^"0^") (deaths ^"0^") (score ^"0^")",name,get_user_userid(id),steam,teamname)		
			
					emit_sound(id,CHAN_BODY,tackle_sounds[random_num(11,14)],1.0,ATTN_NORM,0,PITCH_NORM)
					
					hitTime[id] = get_gametime() + 1.0
		
					if(get_pcvar_num(p_drop) == 1)
						{
						if(random_num(1,get_pcvar_num(p_dropchance)) == 1)
							client_cmd(ent, "drop")
						}
		
					if(get_pcvar_num(p_prone) == 1)
						{
						if(random_num(1,get_pcvar_num(p_pronechance)) == 1)
							client_cmd(ent, "prone")
						}
		
					if(get_pcvar_num(p_fade) == 1)
						{
						if(random_num(1,get_pcvar_num(p_fadechance)) == 1)
							{
							message_begin(MSG_ONE_UNRELIABLE,gMsgScreenFade,{0,0,0},ent)
							write_short(1<<10)  //duraiton
							write_short(1<<10)  //hold time
							write_short(0x0002)  //flags
							write_byte(50) //red
							write_byte(50) //green
							write_byte(50) //blue
							write_byte(150) //alpha
							message_end()
							}
						}
						
					if(get_pcvar_num(p_fade2) == 1)
						{
						message_begin(MSG_ONE_UNRELIABLE,gMsgScreenFade,{0,0,0},id)
						write_short(1<<10)  //duraiton
						write_short(1<<10)  //hold time
						write_short(0x0002)  //flags
						write_byte(50) //red
						write_byte(50) //green
						write_byte(50) //blue
						write_byte(50) //alpha
						message_end()
						}	
					
					if(get_pcvar_num(p_push) == 1)
						{
						if(random_num(1,get_pcvar_num(p_pushchance)) == 1)
							{
							new Float:a[2][3]
							pev(id,pev_origin,a[0])
							pev(ent,pev_origin,a[1])
					
							for(new b = 0; b <= 2; b++) 
								{
								a[1][b] -= a[0][b]
								a[1][b] *= speed / 40
								}
				
							set_pev(ent,pev_velocity,a[1])
							}
						}
					
					if(get_pcvar_num(p_dmg) == 1)
						{
						if(random_num(1,get_pcvar_num(p_dmgchance)) == 1)
							{				
							emit_sound(ent,CHAN_BODY,tackle_sounds[random_num(0,10)],1.0,ATTN_NORM,0,PITCH_NORM)
								
							new steam[32], teamname[32], name[32], steam2[32], teamname2[32], name2[32]
							get_user_authid(id, steam, 31)
							get_user_authid(ent, steam2, 31)
							dod_get_pl_teamname(id, teamname, 31)
							dod_get_pl_teamname(ent, teamname2, 31)
							get_user_name(id, name, 31)
							get_user_name(ent, name2, 31)
														
							if((pev(ent, pev_health) > get_pcvar_num(p_dmgamt)))
								{					
								log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"tackle^") (shots ^"0^") (hits ^"0^") (kills ^"0^") (headshots ^"0^") (tks ^"0^") (damage ^"%d^") (deaths ^"0^") (score ^"0^")",name,get_user_userid(id),steam,teamname,get_pcvar_num(p_dmgamt))
								log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"tackle^") (head ^"0^") (chest ^"1^") (stomach ^"0^") (leftarm ^"0^") (rightarm ^"0^") (leftleg ^"0^") (rightleg ^"0^")",name,get_user_userid(id),steam,teamname)	
								
								set_pev(ent, pev_health, float(pev(ent, pev_health) - get_pcvar_num(p_dmgamt)))
								}
							else
								{
								new ff_tackle = 0
								if(get_user_team(id) == get_user_team(ent))
									ff_tackle = 1
									
								log_message("^"%s<%d><%s><%s>^" killed ^"%s<%d><%s><%s>^" with ^"tackle^"", name, get_user_userid(id), steam, teamname, name2, get_user_userid(ent), steam2, teamname2)
			
								log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"tackle^") (shots ^"0^") (hits ^"0^") (kills ^"1^") (headshots ^"0^") (tks ^"%d^") (damage ^"%d^") (deaths ^"0^") (score ^"0^")",name,get_user_userid(id),steam,teamname,ff_tackle,get_pcvar_num(p_dmgamt))
								log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats2^" (weapon ^"tackle^") (head ^"0^") (chest ^"1^") (stomach ^"0^") (leftarm ^"0^") (rightarm ^"0^") (leftleg ^"0^") (rightleg ^"0^")",name,get_user_userid(id),steam,teamname)
	
								
								//set_msg_block(get_user_msgid("DeathMsg"),BLOCK_ONCE)
								log_block_state = true
								user_silentkill(ent)
								log_block_state = false
								
								message_begin(MSG_ALL, get_user_msgid("DeathMsg"),{0,0,0}, 0)
								write_byte(id)
								write_byte(ent)
								write_byte(0)
								message_end()
								
								dod_set_user_kills(id, dod_get_user_kills(id) + 1,1)
								}
							}
						}
					}
				else
					{
					new steam2[32], teamname2[32], name2[32]
					get_user_authid(id, steam2, 31)
					dod_get_pl_teamname(id, teamname2, 31)
					get_user_name(id, name2, 31)
															
					log_message("^"%s<%d><%s><%s>^" triggered ^"weaponstats^" (weapon ^"tackle^") (shots ^"1^") (hits ^"0^") (kills ^"0^") (headshots ^"0^") (tks ^"0^") (damage ^"0^") (deaths ^"0^") (score ^"0^")",name2,get_user_userid(id),steam2,teamname2)		
					}	
				}
			}
		}	
	return PLUGIN_CONTINUE			
}

///////////////////////////////////////////////////////////////////////////////////////
// Block suicide log
//
public block_log(type, msg[])
{
	return(log_block_state?FMRES_SUPERCEDE:FMRES_IGNORED)
}
